package com.weathereport.entity;

public class ConfortoTermico {
	// Temperatura do ar - Vem do WS
	// Temperatura de radiação - Pesquisar
	// Velocidade do ar - Vem do WS
	// Umidade relativa - Vem do WS
	public static double calcularClo(double TA, double TR, double VEL, double RH, double calibragem) {		
		double CLO = 0.20; // Nivel de roupa - 0.3 até 4
		do {
			CLO += 0.02;
		} while ((calcularPMV(TA, TR, VEL, RH, CLO, calibragem) <= 0) && (CLO <= 4));
		
		return CLO;
	}
	
	public static double calcularPMV(double TA, double TR, double VEL, double RH, double CLO, double calibragem) {
		/*// Variáveis	
		double Ivest = 0.38; // Esse aqui é o canal!!!
		double M = 69.8; // W/m^2
		double W = 0; // W/m^2
		double HR = 0.8; // %
		double Tar = 22; // ºC
		double Trad = 21; // ºC
		double Var = 12; // m/s
		
		// Metabolismo e trabalho
		double p1 = M -W;
		
		double Pvap = HR * (1000 * Math.pow(Math.E, 16.6536 - 4030.183 /(Tar +235)));
		
		// Difusão de calor
		double p2 = 3.05 *Math.pow(10, -3) *(5733 -6.99 *p1 -Pvap);
		
		// Transpiração
		double p3 = 0.42 *(p1 -58.15);
		
		// Respiração latente
		double p4 = 1.7 *Math.pow(10, -5) *M *(5867 -Pvap);
		
		// Respiração sensível
		double p5 = 0.0014 *M *(34 -Tar);
		
		// Fator de vestuário
		double Fvest; 
		if (Ivest < 0.078) {
			Fvest = 1 +1.290 *Ivest;
		} else {
			Fvest = 1.05 +0.645 *Ivest;
		}
		
		// Radiação
		double p6 = 3.96 *Math.pow(10, -8) *Fvest *(Math.pow(Tvest +273, 4) -Math.pow(Trad +273, 4));
		
		// ?
		double H1 = 12.1 *Math.sqrt(Var); // Conferir se eh assim mesmo
		// ou
		double H2 = 2.38 *Math.pow(Tvest -Tar, 0.25);	
		double H = Math.max(H1, H2);

		// Convenção
		double p7 = Fvest *H *(Tvest - Tar);
		
		// Temperatura da pele
		double Tpele = 35.7 -0.0275 *p1;
		
		// Temperatura exterior do vestuario
		//double Tvest = ; //ºC
		//double Tvest = Tpele - Ivest *(p6 +H);
		double Tvest = Tpele - Ivest *((3.96 *Math.pow(10, -8) *Fvest *(Math.pow(Tvest +273, 4) -Math.pow(Trad +273, 4))) + (Fvest *H *(Tvest - Tar)));
				
		
		// Equação de conforto térmico
		double S = p1 -p2 -p3 -p4 -p5 -p6 -p7;
		
		// PMV
		double PMV = (Math.pow(0.303 *Math.E, -0.036 *M) + 0.028) *S;
		
		// Imprime resultado
		System.out.println("PMV = " + PMV); */
		
		// Constantes utilizadas
		final double MET = 1.2; // Trabalho - Achar valor neutro
		
		double FNPS = Math.exp(16.6536 - 4030.183 / (TA + 235));
		double PA = RH * 10 * FNPS;
		double ICL = 0.155 * CLO;
		double M = MET * 58.15;
		
		double FCL;
		if (ICL < 0.078) {
			FCL = 1 + 1.29 * ICL;
		} else {
			FCL = 1.05 + 0.645 * ICL;
		}
    
		double HCF = Math.pow(12.1 * VEL, 0.5);
		double TAA = TA + 273;
		double TRA = TR + 273;

		double TCLA = TAA + (35.5 - TA) / (3.5 * (6.45 * ICL + 0.1));
		double P1 = ICL * FCL;
		double P2 = P1 * 3.96;
		double P3 = P1 * 100;
		double P4 = P1 * TAA;
		double P5 = 308.7 - 0.028 * M + P2 * Math.pow(TRA / 100, 4);
		double XN = TCLA / 100;
		double XF = TCLA / 50;

		int N = 0;
		double EPS = 0.0015;
		double HC = 0;
		while (Math.abs(XN - XF) > EPS) {
			XF = (XF + XN) / 2;
			HCF = 12.1 * Math.pow(VEL, 0.5);
			double HCN = 2.38 * Math.pow(Math.abs(100 * XF - TAA), 0.25);
			
		    if (HCF > HCN) {
		        HC = HCF;
		    } else {
		        HC = HCN;
		    }
		    
		    XN = (P5 + P4 * HC - P2 * Math.pow(XF, 4)) / (100 + P3 * HC);
		    N = N + 1;
		}

		double TCL = 100 * XN - 273;

		// Skinn diff loss
		double HL1 = 3.05 * 0.001 * (5733 - 6.99 * M - PA);
		
		// Sweat loss
		double HL2;
		if (M > 58.15) {
		    HL2 = 0.42 * (M - 58.15);
		} else {
		    HL2 = 0;
		}
		
		// Latent respiration loss
		double HL3 = 1.7 * 1e-05 * M * (5867 - PA);

		// Dry respiration loss
		double HL4 = 0.0014 * M * (34 - TA);

		// Radiation loss
		double HL5 = 3.96 * FCL * (Math.pow(XN, 4) - Math.pow(TRA / 100, 4));

		// Convection loss
		double HL6 = FCL * HC * (TCL - TA);

		// Thermal sensation to skin tran coef
		double TS = 0.303 * Math.exp(-0.036 * M) + 0.028;
		
		/*double TPO;
		if (VEL < 0.2) {
			TPO = 0.5 * TA + 0.5 * TR;
		} else if (VEL < 0.6) {
		    TPO = 0.6 * TA + 0.4 * TR;
		} else {
		    TPO = 0.7 * TA + 0.3 * TR;
		}*/
		
		double PMVval = TS * (M - HL1 - HL2 - HL3 - HL4 - HL5 - HL6);
		
		return PMVval + calibragem;
	}
}